package net.xdclass.controller;

import lombok.extern.slf4j.Slf4j;
import net.xdclass.enums.ShortLinkStateEnum;
import net.xdclass.interceptor.LoginInterceptor;
import net.xdclass.service.LogService;
import net.xdclass.service.ShortLinkService;
import net.xdclass.util.CommonUtil;
import net.xdclass.vo.ShortLinkVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 功能描述
 *
 * @author ASUS
 * @date 2024/07/28  17:24
 */
@Controller
@Slf4j
public class LinkApiController {
    @Autowired
    private ShortLinkService shortLinkService;
    @Autowired
    private LogService logService;
    /**
     * 解析 301还是302，这边是返回http code是302
     * 知识点⼀，为什么要⽤ 301 跳转⽽不是 302 呐？
     * 301 是永久᯿定向，302 是临时᯿定向。短地址⼀经⽣成就不会变化，所以⽤ 301 是同时对服务器压⼒也会有⼀定减少

     * 但是如果使⽤了 301，⽆法统计到短地址被点击的次数。

     * 所以选择302虽然会增加服务器压⼒，但是有很多数据可以获取进⾏分析
     */
    @GetMapping("/{shortLinkCode}")
    public void dispatch(@PathVariable("shortLinkCode") String shortLinkCode, HttpServletRequest request,
                         HttpServletResponse response) {
        try {
            log.info("code:{}",shortLinkCode);
//        1.短链码是否合规
            boolean letterDigit = isLetterDigit(shortLinkCode);
            if (letterDigit) {
                //2.查找短链
                ShortLinkVO shortLinkVO = shortLinkService.parseShortLinkCode(shortLinkCode);
                if(shortLinkVO != null){
                    logService.recordShortLinkLog(request,shortLinkCode, shortLinkVO.getAccountNo());
                }
                //        3.是否能访问
                if (isVisitable(shortLinkVO)){
                    String originalUrl = CommonUtil.removeUrlPrefix(shortLinkVO.getOriginalUrl());
                    response.setHeader("Location", originalUrl);
                    //302跳转
                    response.setStatus(HttpStatus.FOUND.value());
                }else{
                    response.setStatus(HttpStatus.NOT_FOUND.value());
                    return;
                }
            }
        } catch (Exception e) {
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        }
    }

    private static boolean isVisitable(ShortLinkVO shortLinkVO) {
        if ((shortLinkVO != null && shortLinkVO.getExpired().getTime() > CommonUtil.getCurrentTimestamp())) {
            if
            (ShortLinkStateEnum.ACTIVE.name().equalsIgnoreCase(shortLinkVO.getState())) {
                return true;
            }
            //-1代表短链用不过期
        } else if ((shortLinkVO != null && shortLinkVO.getExpired().getTime() == -1)) {
            if
            (ShortLinkStateEnum.ACTIVE.name().equalsIgnoreCase(shortLinkVO.getState())) {
                return true;
            }
        }
        return false;
    }


    /**
     * 仅包括数字和字⺟
     *
     * @param str
     * @return
     */
    private static boolean isLetterDigit(String str) {
        String regex = "^[a-z0-9A-Z]+$";
        return str.matches(regex);
    }
}
